import UIKit

class HUHAImageEditContaner3: UIView {
    // 点击非活跃视图时的闭包
       var SetEditBlock: (() -> Void)?
       // 删除视图的闭包
       var RemoveViewBlock: (() -> Void)?
    // MARK: - Properties
    
    var addImage: UIImage? {
        didSet {
            imageView.image = addImage
        }
    }
    var isEditing: Bool = false {
        didSet {
            removeCtrl.isHidden = !isEditing
            rotateCtrl.isHidden = !isEditing
            if isEditing {
                addGestureRecognizer(panGesture)
                addGestureRecognizer(pinchGesture)
                addGestureRecognizer(rotateGesture)
            } else {
                removeGestureRecognizer(panGesture)
                removeGestureRecognizer(pinchGesture)
                removeGestureRecognizer(rotateGesture)
            }
        }
    }
    
    private lazy var imageView: UIImageView = {
        let imageView = UIImageView(frame: CGRect(x: Ctrl_Radius, y: Ctrl_Radius, width: frame.size.width - Ctrl_Radius * 2, height: frame.size.height - Ctrl_Radius * 2))
        imageView.contentMode = .scaleAspectFit
        imageView.clipsToBounds = true
        return imageView
    }()
    
    private lazy var removeCtrl: UIImageView = {
        let removeCtrl = UIImageView(frame: CGRect(x: 0, y: 0, width: Ctrl_Radius * 2, height: Ctrl_Radius * 2))
        removeCtrl.isUserInteractionEnabled = true
        removeCtrl.image = UIImage(named: "AddView_close")
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(removeCtrlTapGesture(_:)))
        removeCtrl.addGestureRecognizer(tapGesture)
        return removeCtrl
    }()
    
    private lazy var rotateCtrl: UIImageView = {
        let rotateCtrl = UIImageView(frame: CGRect(x: frame.size.width - Ctrl_Radius * 2, y: frame.size.height - Ctrl_Radius * 2, width: Ctrl_Radius * 2, height: Ctrl_Radius * 2))
        rotateCtrl.image = UIImage(named: "AddView_rotate")
        rotateCtrl.isUserInteractionEnabled = true
        rotateCtrl.autoresizingMask = [.flexibleLeftMargin, .flexibleBottomMargin]
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(rotateCtrlPanGesture(_:)))
        rotateCtrl.addGestureRecognizer(panGesture)
        return rotateCtrl
    }()
    
    private var originalPoint = CGPoint(x: 0.5, y: 0.5)
    private var originalWidth: CGFloat = 0
    private var originalHeight: CGFloat = 0
    private var lastCtrlPoint: CGPoint = .zero
    
    private lazy var tapGesture: UITapGestureRecognizer = {
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapGestureAction(_:)))
        return tapGesture
    }()
    
    private lazy var panGesture: UIPanGestureRecognizer = {
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(panGestureAction(_:)))
        return panGesture
    }()
    
    private lazy var pinchGesture: UIPinchGestureRecognizer = {
        let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(pinchAction(_:)))
        pinchGesture.delegate = self
        return pinchGesture
    }()
    
    private lazy var rotateGesture: UIRotationGestureRecognizer = {
        let rotateGesture = UIRotationGestureRecognizer(target: self, action: #selector(rotateAction(_:)))
//        let rotateGesture = UIRotationGestureRecognizer()
        rotateGesture.delegate = self
        return rotateGesture
    }()
    
    // MARK: - Initialization
    
    
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupSubviews()
        setupData()
    }
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupSubviews()
        setupData()
    }
    
    // MARK: - Setup
    
    private func setupSubviews() {
        addSubview(imageView)
        addSubview(rotateCtrl)
        addSubview(removeCtrl)
        addGestureRecognizer(tapGesture)
    }
    
    private func setupData() {
        originalWidth = frame.size.width
        originalHeight = frame.size.height
    }
    
    // MARK: - Gesture Recognizer Actions
    
    @objc private func tapGestureAction(_ tapGesture: UITapGestureRecognizer) {
        if !isEditing {
            SetEditBlock?()
            isEditing = true
        }
    }
    
//    @objc private func rotateAction(_ rotateGesture: UIRotationGestureRecognizer) {
//        guard rotateGesture.numberOfTouches > 1 else { return }
//
//        let p1 = rotateGesture.location(ofTouch: 0, in: self)
//        let p2 = rotateGesture.location(ofTouch: 1, in: self)
//        let newCenter = CGPoint(x: (p1.x + p2.x) / 2, y: (p1.y + p2.y) / 2)
//        originalPoint = CGPoint(x: newCenter.x / bounds.size.width, y: newCenter.y / bounds.size.height)
//
//        var oPoint = convert(getRealOriginalPoint(), to: superview)
//        center = oPoint
//
//        let angle = atan2(center.y - newCenter.y, newCenter.x - center.x)
//        transform = transform.rotated(by: angle)
//
//        oPoint = convert(getRealOriginalPoint(), to: superview)
//        center = CGPoint(x: center.x + (center.x - oPoint.x), y: center.y + (center.y - oPoint.y))
//
//        rotateGesture.rotation = 0
//    }
    @objc func rotateAction(_ rotateGesture: UIRotationGestureRecognizer) {
        guard rotateGesture.numberOfTouches > 1 else {
            return
        }
        transform = CGAffineTransformRotate(transform, rotateGesture.rotation)
        rotateGesture.rotation = 0
    }
    
    @objc private func pinchAction(_ pinchGesture: UIPinchGestureRecognizer) {
        guard pinchGesture.numberOfTouches > 1 else { return }
        let scale = pinchGesture.scale
        if scale < 1 && frame.size.width <= originalWidth / 2 {
            // Do nothing when zooming in to half the original width
        } else {
            transform = transform.scaledBy(x: scale, y: scale)
            fitCtrlScaleX(scaleX: scale, scaleY: scale)
        }

        pinchGesture.scale = 1
    }
    
    @objc private func panGestureAction(_ panGesture: UIPanGestureRecognizer) {
        guard panGesture.state == .changed else { return }
        guard pinchGesture.numberOfTouches <= 1 else {
            panGesture.setTranslation(.zero, in: superview)
            return
        }
        
        let translation = panGesture.translation(in: superview)
        center = CGPoint(x: center.x + translation.x, y: center.y + translation.y)
        panGesture.setTranslation(.zero, in: superview)
    }
    
    @objc private func rotateCtrlPanGesture(_ panGesture: UIPanGestureRecognizer) {
        guard panGesture.state != .began else {
            lastCtrlPoint = convert(rotateCtrl.center, to: superview)
            return
        }
        
        guard panGesture.state != .ended else { return }
        
        let ctrlPoint = panGesture.location(in: superview)
        scaleViewWithCtrlPoint(ctrlPoint)
        rotateViewWithCtrlPoint(ctrlPoint)
        lastCtrlPoint = ctrlPoint
    }
    
    @objc private func removeCtrlTapGesture(_ tapGesture: UITapGestureRecognizer) {
        RemoveViewBlock?()
        removeFromSuperview()
    }
    
    // MARK: - Private Methods
    
    private func fitCtrlScaleX(scaleX: CGFloat, scaleY: CGFloat) {
        removeCtrl.transform = removeCtrl.transform.scaledBy(x: 1 / scaleX, y: 1 / scaleY)
        rotateCtrl.transform = rotateCtrl.transform.scaledBy(x: 1 / scaleX, y: 1 / scaleY)
    }
    
    private func distanceWithStartPoint(_ start: CGPoint, endPoint end: CGPoint) -> CGFloat {
        let x = start.x - end.x
        let y = start.y - end.y
        return sqrt(x * x + y * y)
    }
    
    private func getRealOriginalPoint() -> CGPoint {
        return CGPoint(x: bounds.size.width * originalPoint.x, y: bounds.size.height * originalPoint.y)
    }
    
    private func scaleViewWithCtrlPoint(_ ctrlPoint: CGPoint) {
        let oPoint = convert(getRealOriginalPoint(), to: superview)
        center = oPoint

        let preDistance = distanceWithStartPoint(center, endPoint: lastCtrlPoint)
        let newDistance = distanceWithStartPoint(center, endPoint: ctrlPoint)
        let scale = newDistance / preDistance

        if scale < 1 && frame.size.width <= originalWidth / 2 {
            // 当缩小到初始化宽高的一半时，停止缩小
        } else {
            transform = transform.scaledBy(x: scale, y: scale)
            fitCtrlScaleX(scaleX: scale, scaleY: scale)
        }

        let newCenter = convert(getRealOriginalPoint(), to: superview)
        center = CGPoint(x: center.x + (center.x - newCenter.x), y: center.y + (center.y - newCenter.y))
    }

    private func rotateViewWithCtrlPoint(_ ctrlPoint: CGPoint) {
        var newCenter = ctrlPoint
        let oPoint = convert(getRealOriginalPoint(), to: superview)
        center = CGPoint(x: center.x - (center.x - oPoint.x), y: center.y - (center.y - oPoint.y))

        let angle = atan2(center.y - newCenter.y, newCenter.x - center.x)
        let lastAngle = atan2(center.y - lastCtrlPoint.y, lastCtrlPoint.x - center.x)
        let rotationAngle = -angle + lastAngle
        transform = transform.rotated(by: rotationAngle)

        newCenter = convert(getRealOriginalPoint(), to: superview)
        center = CGPoint(x: center.x + (center.x - newCenter.x), y: center.y + (center.y - newCenter.y))
    }

}

// MARK: - UIGestureRecognizerDelegate

extension HUHAImageEditContaner3: UIGestureRecognizerDelegate {
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
    
    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
        if gestureRecognizer.view == self {
            let p = touch.location(in: self)
            if rotateCtrl.frame.contains(p) {
                return false
            }
        }
        return true
    }
}
